package com.hopes.bizz.poll.alarm.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hopes.bizz.common.core.util.CollectionUtils;
import com.hopes.bizz.poll.alarm.bo.AlarmFactorStatistics;
import com.hopes.bizz.poll.alarm.bo.AlarmStatistics;
import com.hopes.bizz.poll.alarm.bo.PollAlarmGIS;
import com.hopes.bizz.poll.alarm.dto.AlarmStatisticsRequest;
import com.hopes.bizz.poll.alarm.entity.PollAlarmEntity;
import com.hopes.bizz.poll.alarm.entity.PollAlarmExceptionEntity;
import com.hopes.bizz.poll.alarm.entity.PollAlarmNetEntity;
import com.hopes.bizz.poll.alarm.service.PollAlarmExceptionService;
import com.hopes.bizz.poll.alarm.service.PollAlarmNetService;
import com.hopes.bizz.poll.alarm.service.PollAlarmService;
import com.hopes.bizz.poll.alarm.service.PollAlarmStatisticsService;
import com.hopes.bizz.poll.monitor.entity.PollMonitorSiteEntity;
import com.hopes.bizz.poll.monitor.service.PollMonitorSiteService;
import com.hopes.bizz.poll.monitor.service.PollMonitorTypeService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author daijie
 * @version 1.0
 * @date 2023/5/30 15:36
 * @Description:
 */
@Service
public class PollAlarmStatisticsServiceImpl implements PollAlarmStatisticsService {
    @Autowired
    private PollAlarmService pollAlarmService;
    @Autowired
    private PollAlarmNetService pollAlarmNetService;
    @Autowired
    private PollAlarmExceptionService pollAlarmExceptionService;
    @Autowired
    private PollMonitorSiteService pollMonitorSiteService;
    @Autowired
    private PollMonitorTypeService pollMonitorTypeService;

    @Override
    public List<AlarmStatistics> getStatistics(Page page, AlarmStatisticsRequest request) {
        List<AlarmStatistics> result = new ArrayList<>();
        // step 1:查询符合条件的监控点
        LambdaQueryWrapper<PollMonitorSiteEntity> monitorWrapper = Wrappers.lambdaQuery();
        monitorWrapper.eq(Objects.nonNull(request.getOrgId()), PollMonitorSiteEntity::getOrgId, request.getOrgId());
        monitorWrapper.eq(StrUtil.isNotBlank(request.getMonitorType()),PollMonitorSiteEntity::getMonitorType,request.getMonitorType());
        monitorWrapper.eq(Objects.nonNull(request.getMonitorSiteId()),PollMonitorSiteEntity::getId,request.getMonitorSiteId());
        if (Objects.nonNull(request.getMonitorTypeMain())) {
            List<Integer> monitorTypeByMain = pollMonitorTypeService.getMonitorTypeByMain(request.getMonitorTypeMain());
            monitorWrapper.in(PollMonitorSiteEntity::getMonitorType, monitorTypeByMain);
        }

        Page<PollMonitorSiteEntity> selectPage = pollMonitorSiteService.getBaseMapper().selectPage(page, monitorWrapper);
        List<Long> monitorIds = selectPage.getRecords()
                .stream().map(PollMonitorSiteEntity::getId).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(monitorIds)) {
            return result;
        }

        // step 1:查询符合条件的所有报警
        LambdaQueryWrapper<PollAlarmEntity> alarmWrapper = Wrappers.lambdaQuery();
        alarmWrapper.in(CollectionUtils.isNotEmpty(monitorIds), PollAlarmEntity::getMonitorSiteId, monitorIds);
        alarmWrapper.ge(ObjectUtil.isNotNull(request.getBeginTime()), PollAlarmEntity::getAlarmTime, request.getBeginTime());
        alarmWrapper.le(ObjectUtil.isNotNull(request.getEndTime()), PollAlarmEntity::getAlarmTime, request.getEndTime());
        List<PollAlarmEntity> alarmList = pollAlarmService.list(alarmWrapper);

        LambdaQueryWrapper<PollAlarmNetEntity> alarmNetWrapper = Wrappers.lambdaQuery();
        alarmNetWrapper.in(CollectionUtils.isNotEmpty(monitorIds), PollAlarmNetEntity::getMonitorSiteId, monitorIds);
        alarmNetWrapper.ge(ObjectUtil.isNotNull(request.getBeginTime()), PollAlarmNetEntity::getAlarmTime, request.getBeginTime());
        alarmNetWrapper.le(ObjectUtil.isNotNull(request.getEndTime()), PollAlarmNetEntity::getAlarmTime, request.getEndTime());

        List<PollAlarmNetEntity> netList = pollAlarmNetService.list(alarmNetWrapper);

        for (PollAlarmEntity alarmEntity : alarmList) {
            Long monitorSiteId = alarmEntity.getMonitorSiteId();
            Long orgId = alarmEntity.getOrgId();
            Long durationTime = alarmEntity.getDurationTime();
            String factorCode = alarmEntity.getFactorCode();
            AlarmStatistics alarmStatistics;

            Optional<AlarmStatistics> first = result.stream()
                    .filter(it -> it.getMonitorSiteId().equals(monitorSiteId)).findFirst();
            if (first.isEmpty()) {
                alarmStatistics = new AlarmStatistics();
                alarmStatistics.setMonitorSiteId(monitorSiteId);
                alarmStatistics.setOrgId(orgId);
                alarmStatistics.setTime(durationTime);
                alarmStatistics.setNum(1);

                AlarmFactorStatistics factorStatistics = new AlarmFactorStatistics();
                factorStatistics.setFactorCode(factorCode);
                factorStatistics.setTime(durationTime);
                factorStatistics.setNum(1);
                alarmStatistics.setFactors(List.of(factorStatistics));
                result.add(alarmStatistics);
            } else {
                alarmStatistics = first.get();
                alarmStatistics.setNum(alarmStatistics.getNum() + 1);
                alarmStatistics.setTime(alarmStatistics.getTime() + durationTime);
                List<AlarmFactorStatistics> factors = alarmStatistics.getFactors();

                Optional<AlarmFactorStatistics> fff = factors.stream()
                        .filter(it -> it.getFactorCode().equals(factorCode)).findFirst();
                if (fff.isEmpty()) {
                    AlarmFactorStatistics factorStatistics = new AlarmFactorStatistics();
                    factorStatistics.setFactorCode(factorCode);
                    factorStatistics.setTime(durationTime);
                    factorStatistics.setNum(1);
                    alarmStatistics.setFactors(List.of(factorStatistics));
                } else {
                    AlarmFactorStatistics factorStatistics = fff.get();
                    factorStatistics.setNum(factorStatistics.getNum() + 1);
                    factorStatistics.setTime(factorStatistics.getTime() + durationTime);
                }
            }
        }

        for (PollAlarmNetEntity alarmNetEntity : netList) {
            Long monitorSiteId = alarmNetEntity.getMonitorSiteId();
            Long orgId = alarmNetEntity.getOrgId();
            Long durationTime = alarmNetEntity.getDurationTime();
            AlarmStatistics alarmStatistics;

            Optional<AlarmStatistics> first = result.stream()
                    .filter(it -> it.getMonitorSiteId().equals(monitorSiteId)).findFirst();
            if (first.isEmpty()) {
                alarmStatistics = new AlarmStatistics();
                alarmStatistics.setMonitorSiteId(monitorSiteId);
                alarmStatistics.setOrgId(orgId);
                alarmStatistics.setTime(durationTime);
                alarmStatistics.setNum(1);
                alarmStatistics.setFactors(new ArrayList<>());
                result.add(alarmStatistics);
            } else {
                alarmStatistics = first.get();
                alarmStatistics.setNum(alarmStatistics.getNum() + 1);
                alarmStatistics.setTime(alarmStatistics.getTime() + durationTime);
            }
        }

        return result;
    }

    @Override
    public List<PollAlarmGIS> getGisAlarmByMainType(Integer mainType) {
        LambdaQueryWrapper<PollMonitorSiteEntity> monitorWrapper = new LambdaQueryWrapper<>();
        List<Integer> monitorTypeByMain = pollMonitorTypeService.getMonitorTypeByMain(mainType);
        monitorWrapper.in(PollMonitorSiteEntity::getMonitorType, monitorTypeByMain);
        List<Long> monitorIds = pollMonitorSiteService.list(monitorWrapper).stream().map(PollMonitorSiteEntity::getId).collect(Collectors.toList());

        List<PollAlarmGIS> result = new ArrayList<>();
        // 统计超标
        LambdaQueryWrapper<PollAlarmEntity> alarmWrapper = Wrappers.lambdaQuery();
        alarmWrapper.in(PollAlarmEntity::getMonitorSiteId, monitorIds);
        List<PollAlarmEntity> alarmList = pollAlarmService.list(alarmWrapper);
        for (PollAlarmEntity entity : alarmList) {
            PollAlarmGIS gis = new PollAlarmGIS();
            BeanUtils.copyProperties(entity, gis);
            result.add(gis);
        }
        // 统计断网
        LambdaQueryWrapper<PollAlarmNetEntity> netWrapper = Wrappers.lambdaQuery();
        netWrapper.in(PollAlarmNetEntity::getMonitorSiteId, monitorIds);
        List<PollAlarmNetEntity> netList = pollAlarmNetService.list(netWrapper);
        for (PollAlarmNetEntity entity : netList) {
            PollAlarmGIS gis = new PollAlarmGIS();
            BeanUtils.copyProperties(entity, gis);
            result.add(gis);
        }
        // 统计异常
        LambdaQueryWrapper<PollAlarmExceptionEntity> exceptionWrapper = Wrappers.lambdaQuery();
        exceptionWrapper.in(PollAlarmExceptionEntity::getMonitorSiteId, monitorIds);
        List<PollAlarmExceptionEntity> exceptionList = pollAlarmExceptionService.list(exceptionWrapper);
        for (PollAlarmExceptionEntity entity : exceptionList) {
            PollAlarmGIS gis = new PollAlarmGIS();
            BeanUtils.copyProperties(entity, gis);
            result.add(gis);
        }

        return result;
    }
}
